package com.hospital.billcommon.module.business;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hospital.api.RemoteDictionaryService;
import com.hospital.billcommon.module.controller.dto.*;
import com.hospital.billcommon.module.entity.ClinicItemBill;
import com.hospital.billcommon.module.entity.OutpBillItemsTemp;
import com.hospital.billcommon.module.entity.OutpBillitem;
import com.hospital.billcommon.module.entity.PatientRemain;
import com.hospital.billcommon.module.mapper.OutpBillItemsTempMapper;
import com.hospital.billcommon.module.mapper.PatientRemainMapper;
import com.hospital.billcommon.module.mapper.QueryClinicItemMapper;
import com.hospital.billcommon.module.service.OutpPriceService;
import com.hospital.common.core.utils.DateUtil;
import com.hospital.common.core.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description 门诊收费实现
 * @author: liuwei
 * @create 2020/5/15 11:13 上午
 **/
@Slf4j
public class OutpChargeBusiness extends AbstractChargingBusiness<OutpBillitem> {

    private QueryClinicItemMapper queryClinicItemMapper = SpringContextHolder.getBean(QueryClinicItemMapper.class);

    private PatientRemainMapper patientRemainMapper = SpringContextHolder.getBean(PatientRemainMapper.class);

    private OutpPriceService outpPriceService = SpringContextHolder.getBean(OutpPriceService.class);

    private OutpBillItemsTempMapper outpBillItemsTempMapper = SpringContextHolder.getBean(OutpBillItemsTempMapper.class);

    private RemoteDictionaryService remoteDictionaryService = SpringContextHolder.getBean(RemoteDictionaryService.class);



    @Override
    protected List<OutpBillitem> getRefundData(List<RefundBillDetailVo> refundBillDetailList, RefundBillVo refundBillVo) throws Exception {
        List<OutpBillitem> outpBillitemList = outpPriceService.list(new QueryWrapper<OutpBillitem>().apply("rcpt_no={0}", refundBillVo.getNumberNo()));
        String slaveKeyNew = refundBillDetailList.get(0).getSlaveKeyNew();
        String primaryKeyNew = refundBillDetailList.get(0).getPrimaryKeyNew();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date parse = simpleDateFormat.parse(primaryKeyNew);
        outpBillitemList.stream().forEach(outpBillitem -> {
            outpBillitem.setVisitNo(slaveKeyNew);
            Timestamp format = DateUtil.format(parse);
            outpBillitem.setVisitDate(format);
            outpBillitem.setRcptNo(refundBillVo.getRefundRcpt());
            double costs = 0- outpBillitem.getCosts();
            double charges = 0- outpBillitem.getCharges();
            outpBillitem.setCosts(costs);
            outpBillitem.setCharges(charges);
            });
        return outpBillitemList;
    }

    @Override
    protected boolean insertRefundPatientData(List<OutpBillitem> billItemList, RefundBillVo refundBillVo, RestTemplate restTemplate) throws Exception {
        return outpPriceService.insertOutpRefundBillItemList(billItemList, refundBillVo,restTemplate);
    }

    @Override
    protected void setClassOnRcpt(OutpBillitem item, String classOnInpRcpt) {
        item.setClassOnRcpt(classOnInpRcpt);
    }

    @Override
    protected boolean updatePatientData(List<OutpBillitem> billItemList, BillDto billDto, RestTemplate restTemplate) throws Exception {
        return outpPriceService.insertOutpBillItemList(billItemList, billDto,restTemplate);
    }

    @Override
    protected boolean calculateCurrentRemain(double sum, String patientId, String visitId, String chargeType, String createChannel) {
        //增加配置中为集中收费不判断余额
        String chargeWay = patientRemainMapper.getChargeWay();
//        log.info("判断余额:" + patientId + "--是否【chargeWay】：" + chargeWay + "---创建渠道【createChannel】：" + createChannel);
        if ((chargeWay != null && chargeWay.equals("2")) || (createChannel != null && createChannel.equals("1")) || (createChannel != null && createChannel.equals("4"))) {
            return true;
        }
        PatientRemain outpPatientRemain = patientRemainMapper.getOutpPatientRemain(patientId);
//        log.info("查询：outpPatientRemain:" + outpPatientRemain +  "-----------总额：" + String.valueOf(sum));
        double totalPre = 0.0;
        if (outpPatientRemain == null) {
            return totalPre >= sum;
        }
        return outpPatientRemain.getPrepayRemain() >= sum;
    }


    @Override
    protected List<OutpBillitem> unpackItem(BillDto billDto) throws ParseException {
        List<OutpBillitem> outpBillItemList = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String visitDate = billDto.getVisitDate() == null ? null : simpleDateFormat.format(billDto.getVisitDate());
        int index = (null == outpPriceService.getMaxItemNo(visitDate, billDto.getVisitNo())) ? 0 : Integer.parseInt(String.valueOf(outpPriceService.getMaxItemNo(visitDate, billDto.getVisitNo())));
        if (billDto != null && billDto.getClinicTypeList() != null && billDto.getClinicTypeList().size() > 0) {
            for (ClinicType item : billDto.getClinicTypeList()) {
                boolean isPackage = remoteDictionaryService.getclinicItemClassDictList().stream().anyMatch(c -> c.getClassCode().equals(item.getType()));
//                int index = 0;
                for (ClinicItem item1 : item.getClinicItemList()) {
                    if (item1.getClinicItemCode() != null && !item1.getClinicItemCode().trim().equals("")) {
                        long count = outpPriceService.getCount(item1.getClinicItemCode(),item.getType());
                        String primaryDate = item1.getPrimaryDate();
                        Timestamp visit = primaryDate == null || primaryDate.equals("") ? Timestamp.valueOf(visitDate.replace("/", "-")) : Timestamp.valueOf(primaryDate.replace("/", "-"));
                        QueryWrapper<ClinicItemBill> clinicItemBillEntityWrapper = new QueryWrapper<>();
                        clinicItemBillEntityWrapper.eq("clinic_item_class", item.getType()).eq("clinic_item_code", item1.getClinicItemCode());
                        List<ClinicItemBill> clinicItemBills = queryClinicItemMapper.selectList(clinicItemBillEntityWrapper);
                        if (isPackage&&count>0&&!clinicItemBills.isEmpty()) {
                            if (item.getType().equals("I")) {
                                ClinicItemBill clinicItemBill = new ClinicItemBill();
                                clinicItemBill.setChargeItemClass(item.getType());
                                clinicItemBill.setClinicItemClass(item.getType());
                                clinicItemBill.setChargeItemSpec(item1.getItemSpec());
                                clinicItemBill.setClinicItemCode(item1.getClinicItemCode());
                                clinicItemBill.setChargeItemCode(item1.getClinicItemCode());
                                clinicItemBill.setAmount(1);
                                clinicItemBill.setChargeItemNo("1");
                                clinicItemBills.add(clinicItemBill);
                            }
                            List<ClinicItemBill> clinicItemBillList = new ArrayList<>();
                            for (ClinicItemBill clinicItemBill : clinicItemBills) {
                                clinicItemBill.setChargeItemNo(String.valueOf(index + Integer.parseInt(clinicItemBill.getChargeItemNo())));
                                double amount = clinicItemBill.getAmount();
                                if (amount == 0) {
                                    clinicItemBill.setAmount(1);
                                }
                                if (clinicItemBill.getChargeItemSpec() == null) {
                                    clinicItemBill.setChargeItemSpec(item1.getItemSpec());
                                }
                                clinicItemBillList.add(clinicItemBill);
                            }
                            Timestamp finalVisit = visit;
                            outpBillItemList.addAll(clinicItemBillList.stream().map(c -> {
                                try {
                                    return getOutpBillItem(c.getChargeItemClass(), c.getChargeItemCode(), c.getChargeItemSpec(), c.getAmount() * item1.getAmount(),
                                            item1.getPerformedBy(), item1.getPrimaryNo(), finalVisit,
                                            c.getChargeItemNo(), item1.getClinicItemCode(),item1.getCosts());
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                }
                                return null;
                            }).collect(Collectors.toList()));
                        } else {
                            List<OutpBillItemsTemp> outpBillItemsTemp = outpBillItemsTempMapper.getOutpBillItemsTemp(item1.getPrimaryDate(), item1.getPrimaryNo()
                            ,item1.getClinicItemCode());
                            if (!outpBillItemsTemp.isEmpty()) {
                                OutpBillItemsTemp outpBillItemsTemp1 = outpBillItemsTemp.get(0);
                                OutpBillitem outpBillitem = new OutpBillitem();
                                BeanUtils.copyProperties(outpBillItemsTemp1, outpBillitem);
                                outpBillitem.setCosts(Double.parseDouble(outpBillItemsTemp1.getCosts().divide(outpBillItemsTemp1.getAmount(), 3, BigDecimal.ROUND_HALF_UP).toString()));
                                outpBillitem.setCharges(Double.parseDouble(outpBillItemsTemp1.getCharges().divide(outpBillItemsTemp1.getAmount(), 3, BigDecimal.ROUND_HALF_UP).toString()));
                                outpBillitem.setAmount(Double.parseDouble(outpBillItemsTemp1.getAmount().toString()));
                                outpBillitem.setVisitDate(outpBillItemsTemp1.getVisitDate());
                                outpBillitem.setVisitNo(outpBillItemsTemp1.getVisitNo());
                                outpBillItemList.add(outpBillitem);
                            }
                        }
                        index++;
                    }
                    index++;
                }
            }
        }
        return outpBillItemList;
    }

    private OutpBillitem getOutpBillItem(String itemClass, String itemCode, String itemSpec, double totalAmount,
                                         String preformedBy, String visitNo, Timestamp visitDate,
                                         String itemNo, String clinicItemCode,double costs) throws ParseException {
        OutpBillitem outpBillitem = new OutpBillitem();
        outpBillitem.setItemClass(itemClass);
        outpBillitem.setItemCode(itemCode);
        outpBillitem.setItemSpec(itemSpec);
        outpBillitem.setAmount(totalAmount);
        outpBillitem.setPerformedBy(preformedBy);
        outpBillitem.setVisitDate(visitDate==null? DateUtil.nowTime():visitDate);
        outpBillitem.setVisitNo(visitNo==null?outpPriceService.getVisitNo():visitNo);
        outpBillitem.setCosts(costs);
        outpBillitem.setItemNo(itemNo);
        outpBillitem.setClinicItemCode(clinicItemCode);
        outpBillitem.setClassOnRcpt(outpPriceService.getItemOutpRcptClass(itemCode, itemSpec) == null ? itemClass : outpPriceService.getItemOutpRcptClass(itemCode, itemSpec));
        return outpBillitem;
    }


}
